package thinkingInJava.typeinfo.Proxy;
// 动态代理混合
//: typeinfo/SimpleDynamicProxy.java
import java.lang.reflect.*;
import static thinkingInJava.YTool.YPrint.*;

class DynamicProxyHandler implements InvocationHandler {
	private Object proxied;
	public DynamicProxyHandler(Object proxied) {
	  this.proxied = proxied;
	}

	// 这里就可以实现一些类似 hook 的函数过滤,所有被代理的函数调用前都会到这里
	// proxy: 代理接口实例
	// this.proxied: 要(被代理)调用的原始接口
	// method: 当前要调用的方法
	// args: 方法的参数列表
	public Object
	invoke(Object proxy, Method method, Object[] args)
	throws Throwable {
	  System.out.println("**** proxy: " + proxy.getClass() +
	    ", method: " + method + ", args: " + args);
	  System.out.println("this.proxied: " + this.proxied.getClass());
	  if(args != null)
	    for(Object arg : args)
	      System.out.println("  " + arg);
	  return method.invoke(this.proxied, args);
	}
}	

public class SimpleDynamicProxy {
	public static void consumer(Interface iface) {
		iface.doSomething();
		iface.somethingElse("bonobo");
	}
	public static void main(String[] args) {
		RealObject real = new RealObject();
		consumer(real);
		// Insert a proxy and call again:
		Interface proxy = (Interface)Proxy.newProxyInstance(
				Interface.class.getClassLoader(),
				new Class[]{ Interface.class },
				new DynamicProxyHandler(real));
		println("----out proxy: " + proxy.getClass());
		println("----out real: " + real.getClass());
		consumer(proxy);
	}
} /* Output: (95% match)	
doSomething
somethingElse bonobo
----out proxy: class thinkingInJava.typeinfo.Proxy.$Proxy0
----out real: class thinkingInJava.typeinfo.Proxy.RealObject
**** proxy: class thinkingInJava.typeinfo.Proxy.$Proxy0, method: public abstract void thinkingInJava.typeinfo.Proxy.Interface.doSomething(), args: null
this.proxied: class thinkingInJava.typeinfo.Proxy.RealObject
doSomething
**** proxy: class thinkingInJava.typeinfo.Proxy.$Proxy0, method: public abstract void thinkingInJava.typeinfo.Proxy.Interface.somethingElse(java.lang.String), args: [Ljava.lang.Object;@4aa298b7
this.proxied: class thinkingInJava.typeinfo.Proxy.RealObject
  bonobo
somethingElse bonobo
*///:~

